﻿using AutoMapper;
using Modules.Attachment;
using Modules.Common;
using Modules.Corp;
using Modules.Device;
using Modules.Manager;
using Modules.Project;
using Modules.System.Area;
using Modules.System.Dept;
using PmSoft;
using PmSoft.ApplicationContext;
using PmSoft.Entity;
using static Modules.Project.ProjectConstants;
using Modules.System.User;

namespace ManagementApi.Models.Project
{
    public class ProjectInfoDto : OperateDto
    {
        /// <summary>
        /// 项目ID
        ///</summary>
        public int ProjectId { get; set; }

        /// <summary>
        /// 项目分类,交通、水利、住建等
        /// 指工程建设项目的行业主管部门，详见代码表，不在代码表中的不允许入库
        ///</summary>
        public 行业主管部门 IndustryType { get; set; }

        /// <summary>
        /// 行业主管部门
        /// </summary>
        public string? IndustryTypeName { get; set; }

        /// <summary>
        /// 行业主管部门项目编号/住建：西藏自治区建筑市场监管平台项目编号
        /// </summary>
        public string? IndustryPrjNum { get; set; }

        /// <summary>
        /// 项目状态
        /// </summary>
        public 项目状态? PrjStatus { get; set; }

        /// <summary>
        /// 项目状态名称
        /// </summary>
        public string? PrjStatusName { get; set; }

        /// <summary>
        /// 项目名称
        ///</summary>
        public string? Name { get; set; }

        /// <summary>
        /// 项目编号 数据来源平台项目编号
        ///</summary>
        public string? PrjNum { get; set; }

        /// <summary>
        /// 项目分类
        /// </summary>
        public 项目分类 Category { get; set; }

        /// <summary>
        /// 项目分类。参见项目分类字典表
        ///</summary>
        public string? CategoryName { get; set; }

        /// <summary>
        /// 建设规模。参考建设规模字典表
        ///</summary>
        public 项目建设规模类型? SizeType { get; set; }

        /// <summary>
        /// 建设规模。参考建设规模字典表
        ///</summary>
        public string? SizeTypeName { get; set; }

        /// <summary>
        /// 建设性质。参考建设性质分类字典表
        ///</summary>
        public 项目建设性质分类? PropertyNum { get; set; }

        /// <summary>
        /// 建设性质。参考建设性质分类字典表
        ///</summary>
        public string? PropertyNumName { get; set; }

        /// <summary>
        /// 建设单位名称
        ///</summary>
        public string? BuildCorpName { get; set; }

        /// <summary>
        /// 建设单位统一社会信用代码，如果无统一社会信用代码，则填写组织机构代码
        ///</summary>
        public string? BuildCorpCode { get; set; }

        /// <summary>
        /// 总投资，单位：（万元）
        /// </summary>
        public decimal? Invest { get; set; }

        /// <summary>
        /// 开工日期
        /// </summary>
        public DateTime? StartDate { get; set; }

        /// <summary>
        /// 项目地点
        /// </summary>
        public string? Address { get; set; }

        /// <summary>
        /// 项目审核状态
        /// </summary>
        public 项目审核状态? AuditStatus { get; set; }

        /// <summary>
        /// 项目审核状态名称
        /// </summary>
        public string? AuditStatusName { get; set; }

        /// <summary>
        /// 项目审核结果说明
        /// </summary>
        public string? AuditReason { get; set; }

        /// <summary>
        /// 创建数据的项目管理员ID
        /// </summary>
        public int CreateManagerId { get; set; }

        /// <summary>
        /// 创建数据的项目管理员名称
        /// </summary>
        public string? CreateManagerName { get; set; }

        /// <summary>
        /// 考勤设备数量
        /// </summary>
        public int checkInDeviceCount { get; set; }

        /// <summary>
        /// 项目所在城市。参考行政区划字典表
        ///</summary>
        public int CityCode { get; set; }

        /// <summary>
        /// 所在城市 （省-市-县）
        /// </summary>
        public string CityName { get; set; }

        /// <summary>
        /// 是否有施工许可证
        ///</summary>
        public bool IsBuilderLicence { get; set; }

        /// <summary>
        /// 施工许可证编号
        ///</summary>
        public string? BuilderLicences { get; set; }

        /// <summary>
        /// 施工许可证发证日期
        ///</summary>
        public DateTime? BuilderLicencesGrantDate { get; set; }

        /// <summary>
        /// 施工许可证有效期限
        ///</summary>
        public DateTime? BuilderLicencesTermDate { get; set; }

        /// <summary>
        /// 指工程建设项目中标合同价格，单位为元（不需要招投标的项目使用工程造价代替）
        ///</summary>
        public decimal? ContractAmount { get; set; }

        /// <summary>
        /// 工程建设项目资金来源的种类，详见代码表 （项目种类）
        ///</summary>
        public 项目资金来源? FundsSource { get; set; }

        /// <summary>
        /// 工程建设项目资金来源的种类，详见代码表 （项目种类）
        ///</summary>
        public string? FundsSourceName { get; set; }

        /// <summary>
        /// 指工程建设项目合同约定的项目开工日期
        ///</summary>
        public DateTime? ContractStartDate { get; set; }

        /// <summary>
        /// 指工程建设项目合同约定的项目竣工日期
        ///</summary>
        public DateTime? ContractEndDate { get; set; }

        /// <summary>
        /// 竣工日期，精确到 天，格式：yyyy-MM-dd
        ///</summary>
        public DateTime? EndDate { get; set; }

        /// <summary>
        /// 是否树立维权告示牌
        /// 默认值: b'0'
        ///</summary>
        public bool HasSafeguardingBoard { get; set; }

        /// <summary>
        /// 是否有工程款支付担保
        /// 默认值: b'0'
        ///</summary>
        public bool HasEarnestMoney { get; set; }

        /// <summary>
        /// 担保单位名称
        ///</summary>
        public string? EarnestUnitName { get; set; }

        /// <summary>
        /// 担保单位社会统一信用代码
        /// </summary>
        public string? EarnestUnitCode { get; set; }

        /// <summary>
        /// 担保金额
        ///</summary>
        public decimal? EarnestMoney { get; set; }

        /// <summary>
        /// 担保开始日期
        ///</summary>
        public DateTime? EarnestStartDate { get; set; }

        /// <summary>
        /// 担保终止日期
        ///</summary>
        public DateTime? EarnestEndDate { get; set; }

        /// <summary>
        /// 是否需要完善数据
        /// </summary>
        public bool NeedCompletData { get; set; }

        /// <summary>
        /// 班组数量
        /// </summary>
        public int? TotalGroupCount { get; set; }

        /// <summary>
        /// 总包企业id
        ///</summary>
        public int? LumpContractorCorpId { get; set; }

        /// <summary>
        /// 总包企业联系电话
        ///</summary>
        public string? LumpContractorCorpPhoneNum { get; set; }

        /// <summary>
        /// 总包企业名称
        ///</summary>
        public string? LumpContractorCorpName { get; set; }

        /*额外字段*/

        /// <summary>
        /// 是否存在修改申请
        /// </summary>
        public bool ExistUpdate { get; set; }

        public 项目数据来源? DataSource { get; set; }

        /// <summary>
        /// 劳资专管员Id
        /// </summary>
        public int ManagerId { get; set; }

        /// <summary>
        /// 劳资专管员姓名
        /// </summary>
        public string ManagerName { get; set; }

        /// <summary>
        /// 劳资专管员身份证号
        /// </summary>
        public string ManagerCardNumber { get; set; }

        /// <summary>
        /// 监管单位名称
        /// </summary>
        public string DeptName { get; set; }

        public bool IsSync { get; set; }
    }

    public static class ProjectInfoExceptions
    {
        /// <summary>
        /// </summary>
        /// <param name="projectInfo"></param>
        /// <returns></returns>
        public static ProjectInfoDto AsDto(this ProjectInfo projectInfo, IApplicationContext applicationContext)
        {
            ProjectInfoDto projectInfoDto = new();
            var mapper = applicationContext.GetService<IMapper>();
            var dto = mapper.Map(projectInfo, projectInfoDto);
            dto.CategoryName = projectInfo.Category?.GetDescription();
            dto.AuditStatusName = projectInfo.AuditStatus?.GetDescription();
            dto.IndustryTypeName = projectInfo.IndustryType.GetDescription();
            dto.PrjStatusName = projectInfo.PrjStatus?.GetDescription();
            dto.SizeTypeName = projectInfo.SizeType?.GetDescription();
            dto.PropertyNumName = projectInfo.PropertyNum?.GetDescription();
            dto.FundsSourceName = projectInfo.FundsSource?.GetDescription();
            var managerService = applicationContext.GetService<ManagerService>();
            var createManager = managerService.GetManagerInfo(dto.CreateManagerId);
            if (createManager != null)
                dto.CreateManagerName = createManager.Name;
            var corpService = applicationContext.GetService<CorpService>();
            if (dto.LumpContractorCorpId.HasValue && dto.LumpContractorCorpId > 0)
            {
                var corp = corpService.GetCorpInfo(dto.LumpContractorCorpId ?? 0);
                if (corp != null) dto.LumpContractorCorpName = corp.Name;
            }
            var projectCheckinDeviceService = applicationContext.GetService<CheckinDeviceService>();
            dto.checkInDeviceCount = projectCheckinDeviceService.GetProjectCheckinDevicesByProjectId(projectInfo.ProjectId).Count();
            var projectGroupService = applicationContext.GetService<ProjectGroupService>();
            dto.TotalGroupCount = projectGroupService.GetProjectGroupCount(new Modules.CheckIn.ProjectCheckinCountQuery { ProjectId = projectInfo.ProjectId });
            var projectUpdateApplyService = applicationContext.GetService<ProjectUpdateApplyService>();
            dto.ExistUpdate = projectUpdateApplyService.ExistsByPrjIdNoAudit(dto.ProjectId);

            var areaService = applicationContext.GetService<AreaService>();
            dto.CityName = areaService.GetAreaFullName(540000, projectInfo.CityCode, projectInfo.AreaCode);

            #region 劳资专管员信息

            if (projectInfo.ManagerId.HasValue && projectInfo.ManagerId > 0)
            {
                var manager = managerService.GetManagerInfo(projectInfo.ManagerId.Value);
                if (manager != null)
                {
                    dto.ManagerId = manager.ManagerId;
                    dto.ManagerName = manager.Name;
                    dto.ManagerCardNumber = manager.Cardno;
                }
            }

            #endregion 劳资专管员信息

            var deptService = applicationContext.GetService<DeptService>();
            dto.DeptName = deptService.GetSysDept(projectInfo.DeptId)?.Name ?? string.Empty;

            #region 主管单位数据权限

            if (applicationContext.CurrentUser is IDeptUser deptUser)
            {
                if (deptUser.IsSuperAdministrator() || projectInfo.DeptId == deptUser.DeptId)
                    dto.HasEdit = true;
                else dto.HasEdit = false;
            }

            #endregion 主管单位数据权限

            return dto;
        }

        public static List<AttachmentsForm<int>> GetContractAttachments(this ProjectInfo projectInfo)
        {
            var projectAttachmentService = ServiceAccessor.GetService<ProjectAttachmentService>();
            var attachments = projectAttachmentService.GetSysAttachmentByObjectIdAndType(projectInfo.ProjectId, 附件类型.中标通知书, 项目附件租户.Project);
            List<AttachmentsForm<int>> attach = new();
            foreach (var item in attachments)
            {
                AttachmentsForm<int> attachmentsForm = new()
                {
                    AttachmentId = item.Id,
                    AttachmentName = item.FriendlyName,
                };
                attach.Add(attachmentsForm);
            }
            return attach;
        }

        //public static string GetProjectName(this ProjectInfo projectInfo)
        //{
        //    ProjectService projectService = ServiceAccessor.GetService<ProjectService>();
        //    var data = projectService.GetProjectInfo(projectInfo.ProjectId);
        //    if (data == null) return "";
        //    else return data.Name;
        //}

        public static ProjectInfo? AsProject(this ProjectInfo projectInfo)
        {
            ProjectService projectService = ServiceAccessor.GetService<ProjectService>();
            ProjectInfo? data = projectService.GetProjectInfo(projectInfo.ProjectId);
            return data;
        }

        public static ProjectGuaranteePaymentDto? GetGuaranteePayment(this ProjectInfo projectInfo, IApplicationContext applicationContext)
        {
            var projectGuaranteePaymentService = applicationContext.GetService<ProjectGuaranteePaymentService>();
            var projectGuaranteePayment = projectGuaranteePaymentService.GetProjectGuaranteePaymentByProjectId(projectInfo.ProjectId);
            return projectGuaranteePayment?.AsDto(applicationContext);
        }

        /// <summary>
        /// 下拉列表
        /// </summary>
        /// <param name="projectInfo"></param>
        /// <returns></returns>
        public static LabelValue<int> AsPullDownDto(this ProjectInfo projectInfo)
        {
            LabelValue<int> data = new LabelValue<int>();
            data.Value = projectInfo.ProjectId;
            data.Label = projectInfo.Name;
            return data;
        }
    }
}